package per.chenxin.apathy;

import java.io.UnsupportedEncodingException;

public class Util {

    public static String stringToZone(char c, String strCode, String strEscape)
        throws UnsupportedEncodingException {

        return encodeStringTo10(code16ToZone(Character.toString(c).getBytes(strCode), strEscape));
    }

    public static char zoneToChar(String strZone, String strCode, String strEscape)
        throws UnsupportedEncodingException {

        return decode16ToString(Util.zoneToCode16(decode10ToBytes(strZone), strEscape), strCode)
            .charAt(0);
    }

    public static String encodeStringTo16(String str, String strCode)
        throws UnsupportedEncodingException {

        byte[] bytes = str.getBytes(strCode);
        return encodeStringTo16(bytes);
    }

    public static String encodeStringTo16(byte[] bytes) {

        StringBuffer sb = new StringBuffer();
        for (byte b : bytes) {
            sb.append(encode2bTo16(b));
        }
        return sb.toString();
    }

    public static String encodeStringTo10(String str, String strCode)
        throws UnsupportedEncodingException {

        byte[] bytes = str.getBytes(strCode);
        return encodeStringTo10(bytes);
    }

    public static String encodeStringTo10(byte[] bytes) {

        StringBuffer sb = new StringBuffer();
        for (byte b : bytes) {
            sb.append(encode2bTo10(b));
        }
        return sb.toString();
    }

    public static String decode16ToString(String str, String strCode)
        throws UnsupportedEncodingException {

        return decode16ToString(decode16ToBytes(str), strCode);
    }

    public static byte[] decode16ToBytes(String str) {

        byte[] bytes = new byte[2];
        bytes[0] = decode16To2b(str.substring(0, 2));
        bytes[1] = decode16To2b(str.substring(2, 4));
        return bytes;
    }

    public static String decode16ToString(byte[] bytes, String strCode)
        throws UnsupportedEncodingException {

        return new String(bytes, strCode);
    }

    public static String decode10ToString(String str, String strCode)
        throws UnsupportedEncodingException {

        return decode16ToString(decode10ToBytes(str), strCode);
    }

    public static byte[] decode10ToBytes(String str) {

        byte[] bytes = new byte[2];
        bytes[0] = decode10To2b(str.substring(0, 2));
        bytes[1] = decode10To2b(str.substring(2, 4));
        return bytes;
    }

    public static String decode10ToString(byte[] bytes, String strCode)
        throws UnsupportedEncodingException {

        return new String(bytes, strCode);
    }

    public static String encode2bTo16(byte b) {

        byte[] bOut = new byte[2];
        bOut[0] = (byte) ((b & 0x0F0) >>> 4);
        bOut[0] = encode1bTo16(bOut[0]);
        bOut[1] = (byte) (b & 0x0F);
        bOut[1] = encode1bTo16(bOut[1]);
        return new String(bOut);
    }

    public static byte decode16To2b(String str) {

        byte[] bOut = str.getBytes();
        bOut[0] = decode16To1b(bOut[0]);
        bOut[1] = decode16To1b(bOut[1]);
        return (byte) (bOut[0] << 4 | bOut[1]);
    }

    public static String encode2bTo10(byte b) {

        byte[] bOut = new byte[2];
        bOut[0] = (byte) (b / 10);
        bOut[0] = encode1bTo10(bOut[0]);
        bOut[1] = (byte) (b % 10);
        bOut[1] = encode1bTo16(bOut[1]);
        return new String(bOut);
    }

    public static byte decode10To2b(String str) {

        byte[] bOut = str.getBytes();
        bOut[0] = decode10To1b(bOut[0]);
        bOut[1] = decode10To1b(bOut[1]);
        return (byte) (bOut[0] * 10 + bOut[1]);
    }

    public static byte encode1bTo16(byte b) {

        return (byte) (b > 9 ? 'A' + b - 10 : '0' + b);
    }

    public static byte decode16To1b(byte b) {

        if ('0' <= b && b <= '9')
            return (byte) (b - '0');
        else
            return (byte) (b - 'A' + 10);
    }

    public static byte encode1bTo10(byte b) {

        return (byte) ('0' + b);
    }

    public static byte decode10To1b(byte b) {

        return (byte) (b - '0');
    }

    public static byte[] code16ToZone(byte[] bytes, String strEscape) {

        return code16ToZone(bytes, decode16To2b(strEscape));

    }

    public static byte[] code16ToZone(byte[] bytes, byte byteEscape) {

        byte[] bytesReturn = new byte[bytes.length];
        for (int i = 0; i < bytes.length; i++) {
            bytesReturn[i] = (byte) (bytes[i] - byteEscape);
        }

        return bytesReturn;
    }

    public static byte[] zoneToCode16(byte[] bytes, String strEscape) {

        return zoneToCode16(bytes, decode16To2b(strEscape));

    }

    public static byte[] zoneToCode16(byte[] bytes, byte byteEscape) {

        byte[] bytesReturn = new byte[bytes.length];
        for (int i = 0; i < bytes.length; i++) {
            bytesReturn[i] = (byte) (bytes[i] + byteEscape);
        }

        return bytesReturn;
    }

}
